import { XMLLint } from '@/utils/xmlLint'

// 上溯至根节点，判断是否设置Error
export const setParentError = (parent) => {
  if (parent) {
    parent.isError = parent.children.some(l => l.isError)
    setParentError(parent.parent)
  }
}

/**
 * 深度遍历树，检测文件树的代码
 * @param {树} tree 
 * @param {校验规则} tags 
 */
export const lintFileTree = async (tree, tags) => {
  if (tree) {
    let stack = [...tree];//同来存放将来要访问的节点
    while (stack.length !== 0) {
      let item = stack.pop()//正在访问的节点

      if (item.isLeaf) {// 叶子节点 校验文件
        const file = await item.handle.getFile()
        const text = await file.text()
        item.isError = XMLLint.verify(text, undefined, tags).length > 0
        setParentError(item.parent)
      } else {// 文件夹 压栈遍历
        let children = item.children
        for (let i = children.length - 1; i >= 0; i--) {
          stack.push(children[i])
          children[i].parent = item
        }
      }
    }
  }
  return tree;
}

/**
 * 将文件夹handle转换为树形结构
 * @param {打开文件夹获取到的文件夹handle} dirHandle 
 */
export const dirHandle2fileTree = async (dirHandle) => {
  const treeNode = await dirHandle2childern(dirHandle, 'root')
  const treeData = [treeNode]
  return treeData
}

/**
 * 
 * @param {文件夹handle} dirHandle 
 * @param {当前文件夹在树形结构中的的key} currentKey 
 */
const dirHandle2childern = async (dirHandle, currentKey) => {
  const treeNode = {
    handle: dirHandle,
    children: [],
    isLeaf: false,
    title: dirHandle.name,
    key: currentKey
  }

  for await (const handle of dirHandle.values()) {
    if (handle.kind === 'file') {// 文件
      const file = await handle.getFile()
      if (file.type === 'text/xml') {
        treeNode.children.push({
          handle: handle,
          isLeaf: true,
          title: handle.name,
          key: currentKey + '|' + handle.name
        })
      }
    } else { // 文件夹
      const childTreeNode = await dirHandle2childern(handle, currentKey + '|' + handle.name)
      treeNode.children.push(childTreeNode)
    }
  }
  sortFileTree(treeNode.children)
  return treeNode
}

/**
 * 整理当前层级的树形结构，文件夹在前, 文件在后
 * @param {树形结构} treeData 
 */
export const sortFileTree = (treeData) => {
  const len = treeData.length
  if (len > 1) {
    for (let i = 0; i < len - 1; i++) {
      for (let j = 0; j < len - 1 - i; j++) {
        if (isNeedSort(treeData[j], treeData[j + 1])) {
          let temp = treeData[j + 1]
          treeData[j + 1] = treeData[j]
          treeData[j] = temp
        }
      }
    }
  }
}


/**
 * 两个树形节点之间是否应该交换位置
 * @param {前面的节点} nodeBefore 
 * @param {后面的节点} nodeAfter 
 */
const isNeedSort = (nodeBefore, nodeAfter) => {
  // 如果文件在前，文件夹在后，则交换
  if (nodeBefore.isLeaf && !nodeAfter.isLeaf) {
    return true
  }
  // 如果都是文件夹或者都是文件，那么根据名字判断是否该排序
  if (nodeBefore.isLeaf === nodeAfter.isLeaf && nodeBefore.title > nodeAfter.title) {
    return true
  }
  return false
}